package com.jse;

import java.io.File;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ServiceLoader;

import com.jse.Cache.CacheListener;
import com.jse.jdbc.Dao;
import com.jse.jdbc.Jdbc;
import com.jse.json.JsonObject;
import com.jse.server.JseServer;
import com.jse.web.Web;

public class Jse {

	public static final boolean dev=true;//js enjoy 等模板自动检测，极端情况下设置为false
	public static final String encoding="UTF-8";
	public static final Charset charset=StandardCharsets.UTF_8;
	public static final String VERSION="1.0.0";
	public static final String home=System.getProperty("java.home").replace('\\','/');//jdk home
    public static String dir=System.getProperty("user.dir").replace('\\','/');//当前目录 jar运行时
    public static String tmpdir=System.getProperty("java.io.tmpdir").replace('\\','/');//系统临时文件目录
    public static final boolean isWindows=File.separatorChar=='\\';
    public static final JsonObject conf=new JsonObject();
    public static final long pid=ProcessHandle.current().pid();
    public static final Cache cache=new Cache();
    
    public static Class<?> clazz;
    public static String name;
    public static String classpath;
    public static String jspath;//默认js路径
    public static String webapp;
    public static String webapps;
	public static String upload;
	public static File tempdir;
	public static boolean runing;
	public static boolean local;
	public static String redisPrefix;//启用redis初始化时的前缀
    
    public static String jspath() {return jspath;}
    public static String webapps() {return webapps;}
    public static String webapp() {return webapp;}
	public static String webapp(String serverName) {return webapp;}
	
	public static void test(Class<?> clazz) throws Exception{Web.sc=1;run(clazz);}
	public static void run(Class<?> cls,Object...args){
		if(!runing) {
			if(clazz==null)clazz=cls;
			if(classpath==null) {
				var url=cls.getClassLoader().getResource("");
				if(url!=null) {
					classpath=url.getPath();
					int idx=classpath.indexOf(".jar!");
					if(idx!=-1) {
						classpath=classpath.substring(0,idx);
						classpath=classpath.substring(0,classpath.lastIndexOf("/lib/"))+"/src";
					}
				}else {
					classpath=dir+"/src";
				}
				classpath=classpath.replace("file:","").replace("jar:","").replace("/WEB-INF/lib","/WEB-INF/classes");
				if(classpath.charAt(0)=='/'&&classpath.contains(":")&&File.separatorChar!='/')classpath=classpath.substring(1);
				classpath=classpath.replace(cls.getPackageName().replace('.','/'),"");
				
		    }
			if(dir.endsWith("/eclipse")||dir.startsWith("D:/work")){local=true;}
			if(webapp!=null) {dir=webapp;local=false;}
			if(local){
				if(classpath.endsWith("/"))classpath=classpath.substring(0,classpath.length()-1);
				jspath=classpath.replace("/tomcat/web/","/work/")
		    			.replace("/web/WEB-INF/classes","/src")
		    			.replace("/WEB-INF/classes","/src")
		    			.replace("/target/classes","/main/resources")
						.replace("/bin","/src");
		    	if(jspath.endsWith("/target/test-classes/")) {
		    		jspath=webapp=jspath.replace("/target/test-classes/","/src/test/resources");
		    		webapps=dir;
			    	tmpdir=webapp+"/upload/temp";
		    	}else {
		    		webapps=jspath.substring(0,jspath.length()-4);
			    	if(dir.endsWith("/eclipse"))dir=webapps;
			    	webapp=webapps+"/web";
			    	tmpdir=webapps+"/upload/temp";
		    	}
		    	name=dir.substring(dir.lastIndexOf("/")+1);
		    	upload=webapps+"/upload";
		    	if(Fs.exists(classpath,"jse.properties"))conf.loadProp(classpath+"/jse.properties");//加载配置
			    else if(Fs.exists(dir,"jse.properties"))conf.loadProp(dir+"/jse.properties");//加载配置
		    }else {
		    	if(Fs.exists(classpath,"jse.properties"))conf.loadProp(classpath+"/jse.properties");//加载配置
			    else if(Fs.exists(dir,"jse.properties"))conf.loadProp(dir+"/jse.properties");//加载配置
			    classpath=conf.getString("jse.classpath",classpath);
			    if(classpath.endsWith("/"))classpath=classpath.substring(0,classpath.length()-1);
			    jspath=conf.getString("jse.jspath",jspath);
			    webapps=conf.getString("jse.webapps",webapps);
			    webapp=conf.getString("jse.webapp",webapp);
				name=dir.substring(dir.lastIndexOf("/")+1);
				if(!classpath.replace("/WEB-INF/classes","").endsWith(name)) {
					name=classpath.replace("/WEB-INF/classes","");
					name=name.substring(name.lastIndexOf("/")+1);
				}
				if(jspath==null)jspath=classpath;
				if(webapps==null) {
					webapps=jspath.replace("/"+name+"/WEB-INF/classes","");
					if(webapps.endsWith("/src"))webapps=webapps.substring(0,webapps.length()-4);
					if(webapps.endsWith("tomcat/web"))webapps=webapps+"apps";
				}else {
					webapps=webapps.replace("/"+name+"/WEB-INF/classes","");
				}
				if(webapp==null) {
					webapp=jspath.replace("/WEB-INF/classes","");
					if(webapp.endsWith("/src"))webapp=webapp.substring(0,webapp.length()-3)+"web";
				}
				upload=conf.getString("jse.upload",webapps+"/upload");
		    }
			System.out.println("""
					\33[35;1m==================================================
					JSE version:%s name:%s pid:%d
					      dir:%s
					classpath:%s
					   jspath:%s
					  webapps:%s
					   webapp:%s
					   upload:%s
					=================================================="""
	        		.formatted(VERSION,name,pid,dir,classpath,jspath,webapps,webapp,upload));
			if(conf.containsKey("jdbc.dataSource.url")) {//启动JDBC
				if(!Ioc.containsKey("dataSource"))Jdbc.initDataSource(Jse.conf.prifix("jdbc.dataSource."));
				if(!Ioc.containsKey("dao")){Ioc.reg("dao",ServiceLoader.load(Dao.class).findFirst().orElse(new Dao(){}));}
			}
			String jobtable=conf.getString("jse.job");//在db执行定时任务 job
			if(jobtable!=null)Ioc.getBean("dao",Dao.class).query(jobtable).forEach(m->Job.jscheduled(m));
			if("jedis".equals(conf.remove("jse.redis.type"))) {
				redisPrefix=Jse.conf.getString("jse.redis.prefix","");
				Js.eval(new InputStreamReader(Jse.class.getResourceAsStream("/META-INF/jse/jedis.js")));
				Ioc.put("jedisPool",Js.invokeFunction("getJedisPool"));
				var c=(CacheListener)Js.eval("jedisListener");
				c.init();
				cache.setListener(c);
				System.out.println("cache jedis enable");
			}
			Ioc.put("cache",cache);
			if(args.length>0&&args[0]==Boolean.FALSE)return;
//			System.out.println("wc="+Web.sc+" run:"+runing+clazz);
			if(Web.sc==null&&!runing){JseServer.await();}
		}
	}
    
    public static void main(String[] args) throws Exception {//TODO main
		run(Jse.class,args);
	}
}
